818G - Four Melodies - CodeForces Solution


flows graphs *2600

Please click on ads to support us..

C++ Code:

#ifndef _GLIBCXX_NO_ASSERT
#include <cassert>
#endif
#include <cctype>
#include <cerrno>
#include <cfloat>
#include <ciso646>
#include <climits>
#include <clocale>
#include <cmath>
#include <csetjmp>
#include <csignal>
#include <cstdarg>
#include <cstddef>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <ctime>
 
#if __cplusplus >= 201103L
#include <ccomplex>
#include <cfenv>
#include <cinttypes>
#include <cstdbool>
#include <cstdint>
#include <ctgmath>
#include <cwchar>
#include <cwctype>
#endif
 
// C++
#include <algorithm>
#include <bitset>
#include <complex>
#include <deque>
#include <exception>
#include <fstream>
#include <functional>
#include <iomanip>
#include <ios>
#include <iosfwd>
#include <iostream>
#include <istream>
#include <iterator>
#include <limits>
#include <list>
#include <locale>
#include <map>
#include <memory>
#include <new>
#include <numeric>
#include <ostream>
#include <queue>
#include <set>
#include <sstream>
#include <stack>
#include <stdexcept>
#include <streambuf>
#include <string>
#include <typeinfo>
#include <utility>
#include <valarray>
#include <vector>
 
#if __cplusplus >= 201103L
#include <array>
#include <atomic>
#include <chrono>
#include <condition_variable>
#include <forward_list>
#include <future>
#include <initializer_list>
#include <mutex>
#include <random>
#include <ratio>
#include <regex>
#include <scoped_allocator>
#include <system_error>
#include <thread>
#include <tuple>
#include <typeindex>
#include <type_traits>
#include <unordered_map>
#include <unordered_set>
#endif
using namespace std;
using i64 = uint64_t;
//using i128 = __int128;
#define MAXN 100005
#define MAXM 11
#define OP 0
#define CLO 1
#define PLUS 0
#define MINUS 1
#define MUL 2
#define HORZ 0
#define VERT 1
#define ITER 1000
#define INF 1e9
#define EPS 1e-9
#define MOD 1000000007
#define SRC 0
#define PUSH 0
#define POP 1
#define PI acos(-1)
#define UNVISITED INF
#define FOR 0
#define BACK 1
#define OK 2
#define H 19
#define HSH 3
typedef long long ll;
typedef ll hash_t;
//typedef __int128_t lint;
typedef long double ld;
typedef pair<int,int> ii;
typedef pair<int,ll> ilp;
typedef pair<ll,ii> pl;
typedef pair<ll, ll> pll;
typedef pair<ll,int> ppll;
typedef pair<ll,int> li;
typedef pair<ll,ll> iv;
typedef pair<double,int> ip;
typedef tuple<int,int,int> iii;
typedef tuple<ll, ll, ll> tll;
typedef tuple<ld, int, int> iit;
typedef tuple<int,int,ll> i3;
typedef vector<vector<int>> vv;
typedef vector<int> vi;
typedef vector<ll> vl;
typedef vector<ii> vii;
typedef vector<vector<ll>> vll;
//typedef complex<ld> cd;
typedef tuple<ll,int,int> tpl;
#define pb push_back
#define eb emplace_back
#define ppb pop_back
#define ppf pop_front
#define pf push_front
#define bk back()
#define frnt front()
#define ins insert
#define er erase
#define sc second
#define fr first
#define mp make_pair
#define mt make_tuple
#define repl(i,x,y) for (int i = (x); i <= (y); ++i)
#define rep(i,x,y) for (int i = (x); i < (y); ++i)
#define rev(i,x,y) for (int i = (x); i >= (y); --i)
#define repd(i,x,y,d) for (int i = (x); i < (y); i += (d))
#define LSOne(S) (S & (-S))
#define trav(i,v) for (auto &i : v)
#define foreach(it,v) for (auto it = begin(v); it != end(v); ++it)
#define bend(v) begin(v), end(v)
#define rbend(v) (v).rbegin(), (v).rend()
#define sortarr(v) sort(bend(v))
#define rsortarr(v) sort(rbend(v))
#define rdup(v) v.er(unique(bend(v)), end(v))
#define rstreak(v) v.resize(unique(bend(v)) - begin(v))
#define extend(A,B) A.insert(end(A), bend(B))
#define sz(A) (int)(A.size())
#define fill(V) iota(bend(V), (0))
#define vfill(V, st) iota(bend(V), st)
#define sum(V) accumulate(bend(V), 0LL)
#define vsum(V, st) accumulate(bend(V), (ll)(st))
template<class T> bool ckmin(T &a, T b) { return a > b ? a = b, 1 : 0; };
template<class T> bool ckmax(T &a, T b) { return a < b ? a = b, 1 : 0; };
template<class T> void amax(T &a, T b, T c) { a = max(b, c); };
template<class T> void amin(T &a, T b, T c) { a = min(b, c); };
template<class T> T getmax(vector<T> &v) { return *max_element(bend(v)); };
template<class T> T getmin(vector<T> &v) { return *min_element(bend(v)); };
template<class vi> void distinct(vi &a) { sortarr(a); rdup(a); };
template<class T> int compress(vector<T> &v, T &val) { return (int)(lower_bound(bend(v), val) - begin(v)); };
template<class T> auto vfind(vector<T> &v, T val) {
    return find(bend(v), val);
}
template<class T> auto verase(vector<T> &v, T val) {
    return v.er(vfind(v, val));
}
template<class T> void revarr(vector<T> &v) { reverse(bend(v)); };
template<class T> void print(vector<T> &v, char end) { trav(i,v) cout << i << end;
}
 
mt19937 gen((int)(chrono::steady_clock::now().time_since_epoch().count()));
ll rng(ll l,ll r) {return uniform_int_distribution<ll>(l,r)(gen);}
 
void fast_io() {
    ios::sync_with_stdio(false);
    cin.tie(NULL); cout.tie(NULL);
}
 
ll gcd(ll a, ll b) {
    if (!a) return b;
    return gcd(b % a, a);
}
 
vector<ii> mv = {{-1,0}, {-1,1}, {0,1}, {1,1}, {1,0}, {1,-1}, {0,-1}, {-1,-1}};
template<class T = long long>
struct mcmf {
    struct edge {
        int u, v, rv;
        T C, flow, w;
        edge(T C, T flow, int u, int v, T w, int rv) : C(C), flow(flow), u(u), v(v), w(w), rv(rv) {}
    };
 
    vector<edge> e;
    vector<vector<int>> g;
    vector<T> level;
    vector<int> parent, p_edge;
    int s, t, n;
    mcmf(int num) { //num is the total number of vertices to initialise to
        n = num, s = n - 2, t = n - 1;
        g.resize(n);
        parent.resize(n), level.resize(n), p_edge.resize(n);
    }
    
    void reset() {
        g.clear(), e.clear();
        g.resize(n);
    }
    
    void update(int src, int dst) { //update the source and sink
        s = src , t = dst;
    }
    
    void addEdge(int src, int dst, T cap, T cost) {
        edge e1 = edge(cap, 0, src, dst, cost, (int)(g[dst].size()));
        edge e2 = edge(0, 0, dst, src, -cost, (int)(g[src].size()));
        g[src].push_back((int)(e.size()));
        e.push_back(e1);
        g[dst].push_back((int)(e.size()));
        e.push_back(e2);
    }
 
    bool bfs() {
        for (int i = 0; i < n; ++i) {
            level[i] = numeric_limits<T>::max();
            parent[i] = -1;
        }
        vector<bool> inq(n, false);
        level[s] = 0;
        deque<int> q;
        q.push_front(s);
        while (!q.empty()) {
            int u = q.front();
            q.pop_front();
            inq[u] = false;
            for (int i = 0; i < g[u].size(); i++) {
                edge &e1 = e[g[u][i]];
                if (level[e1.v] > level[u] + e1.w && e1.C > e1.flow) {
                    level[e1.v] = level[u] + e1.w;
                    parent[e1.v] = u;
                    if (!inq[e1.v]) {
                        inq[e1.v] = true;
                        q.push_back(e1.v);
                    }
                    p_edge[e1.v] = i;
                }
            }
        }
        if (level[t] == numeric_limits<T>::max()) return false;
        return true;
    }
 
    pair<T,T> run() { //first entry is max flow, second entry is min cost
        T res = 0, cost = 0;
        while (bfs()) {
            T flow = numeric_limits<T>::max();
            for (int curr = t; curr != s; curr = parent[curr]) {
                int pu = parent[curr], pr = p_edge[curr];
                flow = min(flow, e[g[pu][pr]].C - e[g[pu][pr]].flow);
            }
           
            res += flow;
            for (int curr = t; curr != s; curr = parent[curr]) {
                int pu = parent[curr], pr = p_edge[curr], bc = e[g[pu][pr]].rv;
                e[g[pu][pr]].flow += flow;
                cost += e[g[pu][pr]].w * flow;
                e[g[curr][bc]].flow -= flow;
            }
        }
        return {res, cost};
    }
    bool got_flow(int u, int v) {
        for (int &idx : g[u]) {
            edge &edg = e[idx];
            if (edg.v == v) return e.flow > 0;
        }
        return false;
    }
};

int lm[7], lst[MAXN];
int main() {
    fast_io();
    memset(lst, -1, sizeof(lst));
    memset(lm, -1, sizeof(lm));
    //int t; cin >> t;
    //while (t--) solve();
    int n; cin >> n;
    int tvertices = 4 + 2 * n + 2;
    mcmf<int> mf(tvertices);
    int s = tvertices - 2, t = tvertices - 1;
    //add edges betwee sources and melody vertices
    rep(i,0,4) mf.addEdge(s, i, 1, 0);
    //whenever we deal with adding n^2 edges, try to add edges in a chain
    rep(i,0,n) {
        int a; cin >> a;
        //add edge from medlody vertices to starting vertices of the subsequence
        rep(j,0,4) mf.addEdge(j, 4 + 2 * i, 1, -1);
        //add capacity edges because of vertex splitting
        mf.addEdge(4 + 2 * i, 4 + 2 * i + 1, 1, 0);
        //add edges between the second vertex and the sink to end the subsequence
        mf.addEdge(4 + 2 * i + 1, t, 1, 0);
        // add edges between valid neighbours in a subsequence
        if (lm[a % 7] != -1)  {
            mf.addEdge(4 + 2 * lm[a % 7] + 1, 4 + 2 * i, 1, -1);
            mf.addEdge(4 + 2 * lm[a % 7], 4 + 2 * i, INF, 0);
        }
        if (a - 1 > 0 && lst[a - 1] != -1)  mf.addEdge(4 + 2 * lst[a - 1] + 1, 4 + 2 * i, 1, -1);
        if (lst[a + 1] != -1)  mf.addEdge(4 + 2 * lst[a + 1] + 1, 4 + 2 * i, 1, -1);
        if (lst[a] != -1) { //jump along vertices with the same value and the same modulo to speedup
            mf.addEdge(4 + 2 * lst[a], 4 + 2 * i, INF, 0);
        }
        lm[a % 7] = lst[a] = i;
    }
    cout << -mf.run().sc;
}


Comments

Submit
0 Comments
More Questions

1637A - Sorting Parts
509A - Maximum in Table
1647C - Madoka and Childish Pranks
689B - Mike and Shortcuts
379B - New Year Present
1498A - GCD Sum
1277C - As Simple as One and Two
1301A - Three Strings
460A - Vasya and Socks
1624C - Division by Two and Permutation
1288A - Deadline
1617A - Forbidden Subsequence
914A - Perfect Squares
873D - Merge Sort
1251A - Broken Keyboard
463B - Caisa and Pylons
584A - Olesya and Rodion
799A - Carrot Cakes
1569B - Chess Tournament
1047B - Cover Points
1381B - Unmerge
1256A - Payment Without Change
908B - New Year and Buggy Bot
979A - Pizza Pizza Pizza
731A - Night at the Museum
742A - Arpa’s hard exam and Mehrdad’s naive cheat
1492A - Three swimmers
1360E - Polygon
1517D - Explorer Space
1230B - Ania and Minimizing